/*
 * Uds_Server.cpp

 *
 *  Created on: 26.08.2014
 *      Author: Dave
 */

#include "MQ_Server.h"


MQ_Server::MQ_Server(Prngd_State state)
{
	msgqueue = 0;
	msgqueue = 0;
	mqc = 0;
	msg = '\0';
	msgSize = 0;
	prngd = new Prngd(state);
	lfname = MQ_LOG;
	flog = true;

	work_thread_active = true;
	StartWorkerThread();

}


void MQ_Server::thread_listen(pthread_t parent_th)
{
	char buffer[BUFFER_SIZE];
	int size;
	worker_busy = false;

	memset(buffer, '\0', BUFFER_SIZE);


	while(listen_thread_active)
	{
		size = mq_receive(msgqueue, buffer, BUFFER_SIZE, 0);
		log(" Nachricht aus Messagequeue entnommen.");

		if(size > 0)
		{
			if(!worker_busy)
			{
				if(strcmp(buffer, "/exit") == 0)
				{
					listen_thread_active = false;
					log(" Sende SIGUSR2 an worker");
					pthread_kill(parent_th, SIGUSR2);
				}
				else
				{
					worker_busy = true;
					strncpy(work_buffer, buffer, BUFFER_SIZE);
					log(" Sende SIGUSR1 an worker");
					pthread_kill(parent_th, SIGUSR1);
				}
				memset(buffer, '\0', BUFFER_SIZE);
			}
		}
	}
	pthread_kill(parent_th, SIGPOLL);
}


void MQ_Server::thread_work()
{
	char* result = NULL;
	int result_size = 0;
	active = true;

	mq_unlink("/prngdsq");
	mq_unlink("/prngdcq");

	attr.mq_flags = 0;
	attr.mq_maxmsg = 10;
	attr.mq_msgsize = 256; //TODO: msgsize wie festlegen ?
	attr.mq_curmsgs = 0;


	msgqueue = mq_open( "/prngdsq", O_CREAT| O_RDONLY, 0666, &attr);
	if(msgqueue > 0)
		log(" Msgqueue für Server angelegt.");;

	attr.mq_msgsize = 8192; //maxmiale standardgröße für eine msg

	mqc = mq_open( "/prngdcq", O_CREAT| O_WRONLY, 0666, &attr);
	if(mqc > 0)
			log(" Msgqueue für Client angelegt.");;



	configSignals();

	while(work_thread_active)
	{
		param_count = 0;
		listen_thread_active= true;
		StartListenerThread((pthread_t)pthread_self());

		while(listen_thread_active)
		{
			sigwait(&sigmask, &sig);
			switch(sig)
			{
				case SIGUSR1:

					logTemp->append(" Client hat folgendes gesendet: ");
					logTemp->append(work_buffer, BUFFER_SIZE);
					log((char*)logTemp->c_str());

					getParams();

					log(" Starte Erzeugung von Zufallsbits");

					result = prngd->work(param_count, params);
					result_size = prngd->getResultSize();
					log(" Erzeugung von Zufallsbits beendet");

					if(mq_send(mqc, result, result_size, 0) < 0)
						log(" !Zufallsbits konnten nicht gesendet werden.");
					else
						log(" Zufallsbits an Client gesendet.");

					deleteParams();
					memset(work_buffer, '\0', BUFFER_SIZE);
					worker_busy = false;

					break;
				case SIGUSR2:
					//Server got the command to shutdown
					listen_thread_active = false;
					work_thread_active = false;
					break;
				default:
					//client closed connection, but server will still run and wait for further clients
					listen_thread_active = false;
					work_thread_active = false;
					log(" /exit wurde empfangen, MQ Server wird heruntergefahren.");
					break;
			}
			param_count = 0;
		}
	}
	mq_close(msgqueue);
	mq_close(mqc);
	mq_unlink("/prngdsq");
	mq_unlink("/prngdcq");
	log(" Message Queue von Server und Client freigegeben.");
	//wait for our listen_thread to be closed
	log(" Warte auf beenden von Listener");
	WaitForListenerThreadToExit();
	log(" MQ Server beendet.");
	active = false;

}

